package liantiaoxifen.server;

import java.io.*;
import java.net.Socket;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import java.util.Set;

public class Service implements Runnable{

        private Socket socket;
        PrintWriter pw=null;
        private String userName=null;
        private String nickName=null;
        private static Connection connection;
        private BufferedReader br;
        private Map<String,PrintWriter> pws;

        private static Dao  dao=new Dao(connection);

        public Service(Socket socket, Map<String,PrintWriter> pws){
            this.socket=socket;
            this.pws=pws;
        }
        static {
            //数据库连接赋值~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            try {
                connection = DBUtil.getConnextion("ltsdb");
                dao=new Dao(connection);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }


        //用户会话处理~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~run()方法
        public void run(){
            int i=0;
            try {
                InputStream in=socket.getInputStream();
                InputStreamReader isr=new InputStreamReader(in);
                br=new BufferedReader(isr);

                OutputStream out=socket.getOutputStream();
                OutputStreamWriter osw=new OutputStreamWriter(out);
                BufferedWriter bw=new BufferedWriter(osw);
                pw=new PrintWriter(bw,true);


                //处理登录和注册
                int  key=Integer.parseInt(br.readLine());

                if (key==1){
                    i= Loginhandle();
                }else if (key==2){
                    while (true){
                        registerhander();
                        if (Integer.parseInt(br.readLine())==2){
                            break;
                        }
                    }
                }


                //异常处理
            } catch (IOException e) {
                System.out.println("");
                e.printStackTrace();
            }finally {
                try {
                    socket.close();
                } catch (IOException e) {
                    System.out.println("");
                    e.printStackTrace();
                }finally {
                    synchronized (pws){
                        if (i==2)
                        pws.remove(userName);
                        Controller.count--;
                    }
                }
            }
        }




        //处理登录会话
        private int Loginhandle(){
            try {
                ResultSet r= null;
                int i=1;
                boolean key=false;

                //处理登录 用户名或密码错误5次自动退出程序
                while (i<=5) {
                    userName=br.readLine();
                    String passWord=br.readLine();
                    r= dao.selectDB("select username ,password,nickname from user where username=? and password=?",userName,passWord);
                    key=r.next();
                    if (key)break;
                    pw.println("false");
                    if(i==5) return 2;
                }
                //输入正确
                if (key){
                    nickName=r.getString("nickname");
                    synchronized (pws){
                        Set<String> s= pws.keySet();
                        for (String userN:s){
                            if (userN.equals(userName)){
                                pw.println("falsef");
                                return 1;
                            }
                        }
                        pws.put(userName,pw);
                    }
                    pw.println("true");
                    sendMessages("当前在线人数"+pws.size()+"人，当前已连接但未输入昵称的人数为"+(Controller.count-pws.size())+"人");  //(Controller.count-pws.size())


                    String message;
                    while ((message=br.readLine())!=null){
                        if (message.startsWith("@")){
                            sendSomeOne(message);
                        }else {
                            sendMessages(nickName+"说："+message);
                        }
                    }
                    //输入错误
                }else{
                    pw.println("false");
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }finally {
                try {
                    socket.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return 2;
        }

        //处理注册会话
        private void registerhander(){
            try {

                //接受用户注册输入
                String userName=br.readLine();
                String passWord=br.readLine();
                String nickName=br.readLine();
                ResultSet r= dao.registerDB(userName);

                if (r.next()){
                    pw.println("false");
                }else{
                    //没有重复 插入用户数据到数据库 执行注册功能
                    String sql2="insert into user(username ,password,nickname) values(?,?,?)";
                    PreparedStatement ps2=connection.prepareStatement(sql2);
                    ps2.setString(1,userName);
                    ps2.setString(2,passWord);
                    ps2.setString(3,nickName);
                    int i=ps2.executeUpdate();
                    if (i>0){
                        pw.println("true");
                        Loginhandle();
                    }
                }

            } catch (IOException e) {
                throw new RuntimeException(e);
            }catch (SQLException e){
                 throw new RuntimeException();
            }
        }

        //私发消息给某人
        private void sendSomeOne(String message){
            if (message.matches("@.+:.+")){
                String name=message.substring(1,message.indexOf(":"));
                if (pws.containsKey(selectUsername(name))){
                    String ms=message.substring(message.indexOf(":")+1);
                    pws.get(selectUsername(name)).println(nickName+"悄悄对你说："+ms);
                    System.out.println(nickName+"私发了一条消息给"+name+"!");
                    pw.println("已私发给"+name+"！");
                }else{
                    pw.println("对方用户不存在！请再次输入");
                }
            }else{
                pw.println("请输入正确的私发消息格式 正确格式为 @昵称:消息");
            }
        }

        //服务器本地以及 广播发消息
        private void sendMessages(String message){
            System.out.println(message);
            synchronized (pws){
                for (PrintWriter p:pws.values()){
                    p.println(message);
                }
            }
        }

        //根据昵称返回用户名
        private String selectUsername(String nickName){
            try {
                String sql="select username from user where nickname=?";
                PreparedStatement ps = connection.prepareStatement(sql);
                ps.setString(1,nickName);
                ResultSet r=ps.executeQuery();
                if (r.next()==true){
                    return r.getString("username");
                }
                return null;
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }

}
